package com.example.testclient.netty;

import android.util.Log;

import com.example.testclient.MainActivity;
import com.google.gson.Gson;
import com.example.testclient.eventBusBean.ConnectStatusBean;
import com.haoxy.common.model.FileBean;
import com.haoxy.common.model.MessageBean;
import com.haoxy.common.model.PingBean;

import org.greenrobot.eventbus.EventBus;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelProgressiveFuture;
import io.netty.channel.ChannelProgressiveFutureListener;
import io.netty.channel.ChannelProgressivePromise;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

/**
 * netty连接及数据处理
 *
 * @author Medvalley
 */
@ChannelHandler.Sharable
public class NettyDataHandler extends ChannelHandlerAdapter {

    public static final String TAG = "NETTY_TAG";
    public ChannelHandlerContext ctx;
    private boolean reconnect = true;//是否断线重连，true重连，false不重连

    public void setReconnect(boolean reconnect) {
        this.reconnect = reconnect;
    }

    /**
     * 连接成功会调用
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        this.ctx = ctx;
        EventBus.getDefault().post(new ConnectStatusBean("1"));
        Log.w(TAG, "连接已建立,远程地址：" + ctx.channel().remoteAddress());
    }

    /**
     * 连接断开会调用
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        this.ctx = ctx;
        EventBus.getDefault().post(new ConnectStatusBean("2"));
        Log.w(TAG, "连接已断开");
        //断线重连操作
        if (reconnect) {
            Log.w(TAG, "尝试重连");
            NettyClient.getInstance().stop();
            NettyClient.getInstance().start(MainActivity.ADRESS, MainActivity.PORT);
        }
    }

    /**
     * 收到消息会调用
     *
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        this.ctx = ctx;
//        Log.w(TAG, "客户端得到服务端发来的消息");
        if (msg instanceof PingBean) {
            Log.w("PING_TAG", new Gson().toJson((PingBean) msg));
        } else if (msg instanceof MessageBean) {
            Log.w("MESSAGE_TAG", "收到文字数据" + new Gson().toJson(msg));
            EventBus.getDefault().post((MessageBean) msg);
        }
    }

    /**
     * 利用读写空闲发送心跳
     *
     * @param ctx
     * @param evt
     * @throws Exception
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        this.ctx = ctx;
        if (evt instanceof IdleStateEvent) {
            IdleState state = ((IdleStateEvent) evt).state();
            if (state == IdleState.ALL_IDLE) {
                //发送心跳
                ctx.channel().writeAndFlush(new PingBean());
//                ByteBuf buf = Unpooled.copiedBuffer(PACKETSEPARATOR.getBytes(StandardCharsets.UTF_8));
//                ctx.channel().writeAndFlush(buf);
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    /**
     * 连接异常会调用
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Log.w(TAG, "连接异常:" + cause.getMessage());
    }

    /**
     * 发送消息实体类
     *
     * @param messageBean
     */
    public void sendMessage(MessageBean messageBean) {
        ctx.channel().writeAndFlush(messageBean).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    Log.w(TAG, "sendMessage===Success ");
                } else {
                    Log.w(TAG, "sendMessage===Failure ");
                }
            }
        });
//        ByteBuf buf = Unpooled.copiedBuffer(PACKETSEPARATOR.getBytes(StandardCharsets.UTF_8));
//        ctx.channel().writeAndFlush(buf);
    }

    /**
     * 发送文件实体类
     *
     * @param fileBean
     */
    public void sendFile(FileBean fileBean) {

        ChannelProgressivePromise progressivePromise = ctx.channel().newProgressivePromise();
        progressivePromise.addListener(new ChannelProgressiveFutureListener() {
            @Override
            public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) throws Exception {
                Log.w(TAG, "sendFile===发送中 ");
            }

            @Override
            public void operationComplete(ChannelProgressiveFuture future) throws Exception {
                Log.w(TAG, "sendFile===完成 ");
            }
        });

        ctx.channel().writeAndFlush(fileBean, progressivePromise);

//        Log.w(TAG, "sendFile===begin ");
//        MessageBean messageBean = new MessageBean();
//        messageBean.setMsg("客户端文件已发送");
//        ctx.channel().writeAndFlush(messageBean);
//        ctx.channel().writeAndFlush(fileBean).addListener(new ChannelFutureListener() {
//            @Override
//            public void operationComplete(ChannelFuture future) throws Exception {
//                if (future.isSuccess()) {
//                    Log.w(TAG, "sendFile===Success ");
//                } else {
//                    Log.w(TAG, "sendFile===Failure ");
//                }
//            }
//        });
//        ByteBuf buf = Unpooled.copiedBuffer(PACKETSEPARATOR.getBytes(StandardCharsets.UTF_8));
//        ctx.channel().writeAndFlush(buf);
    }
}
